package 自己写一个json解析器测试;

import java.util.ArrayList;

public class 语法解析 {

    private TokenList tokenList;

    private void checkExpectToken(TokenType tokenType, ArrayList<TokenType> expectToken) {
        String tokenTypeStr = tokenType.toString();

        StringBuilder stringBuilder = new StringBuilder();

        for (TokenType tokentype : expectToken) {
            stringBuilder.append(tokentype.toString());
        }
        String s = stringBuilder.toString();
        if (!(s.contains(tokenTypeStr))) {
            try {
                throw new Exception("非法期望");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public Object parse(TokenList tokenList) {
        this.tokenList = tokenList;

        return parse1();
    }

    private Object parse1() {
        Token currentToken = tokenList.current();
        if (currentToken == null) {
            return new JsonObject();
        } else if (currentToken.getTokenType() == TokenType.开始对象) {
            return parseJsonObject();
        } else if (currentToken.getTokenType() == TokenType.开始数组) {
            return parseJsonArray();
        }

        return null;
    }

    private Object parseJsonObject() {
        JsonObject jsonObject = new JsonObject();

        // 开始的时候期望是一个字符串
        ArrayList<TokenType> expectToken = new ArrayList<>();
        expectToken.add(TokenType.字符串);
        expectToken.add(TokenType.布尔值);
        expectToken.add(TokenType.字符串);
        expectToken.add(TokenType.开始对象);
        expectToken.add(TokenType.开始数组);
        expectToken.add(TokenType.结束对象);

        String key = null;
        Object value = null;

        while (tokenList.hasMore()) {
            Token currentToken = tokenList.next();
            TokenType tokenType = currentToken.getTokenType();
            String tokenValue = currentToken.getValue();

            switch (tokenType) {
                case 开始对象:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key,parseJsonObject() ); // key 可以是空  递归
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束对象);
                    expectToken.add(TokenType.END_DOCUMENT);
                    break;
                case 结束对象:
                    checkExpectToken(tokenType, expectToken);
                    return jsonObject;
                case 开始数组:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, parseJsonArray());
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束对象);
                    break;
                case NULL:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, null);
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束对象);
                    break;
                case 布尔值:
                    checkExpectToken(tokenType, expectToken);
                    jsonObject.put(key, Boolean.valueOf(currentToken.getValue()));
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束对象);
                    break;
                case 字符串:
                    checkExpectToken(tokenType, expectToken);
                    Token prevToken = tokenList.prev();
                    if (prevToken.getTokenType() == TokenType.冒号) {
                        value = currentToken.getValue();
                        jsonObject.put(key, value);
                        expectToken.clear();
                        expectToken.add(TokenType.逗号);
                        expectToken.add(TokenType.结束对象);
                    } else {
                        key = currentToken.getValue();
                        expectToken.clear();
                        expectToken.add(TokenType.冒号);
                    }
                    break;
                case 冒号:
                    checkExpectToken(tokenType, expectToken);
                    expectToken.clear();
                    expectToken.add(TokenType.布尔值);
                    expectToken.add(TokenType.字符串);
                    expectToken.add(TokenType.开始对象);
                    expectToken.add(TokenType.开始数组);
                    expectToken.add(TokenType.结束对象);
                    break;
                case 逗号:
                    checkExpectToken(tokenType, expectToken);
                    expectToken.clear();
                    expectToken.add(TokenType.字符串);
                    expectToken.add(TokenType.开始对象);
                    break;
                case END_DOCUMENT:
                    checkExpectToken(tokenType, expectToken);
                    return jsonObject;
            }
        }

        return null;
    }

    private Object parseJsonArray() {
        JsonArray jsonArray = new JsonArray();

        // 开始的时候期望是这些
        ArrayList<TokenType> expectToken = new ArrayList<>();
        expectToken.add(TokenType.字符串);
        expectToken.add(TokenType.布尔值);
        expectToken.add(TokenType.字符串);
        expectToken.add(TokenType.开始对象);
        expectToken.add(TokenType.开始数组);
        expectToken.add(TokenType.结束数组);
        expectToken.add(TokenType.NULL);

        while (tokenList.hasMore()) {
            Token currentToken = tokenList.next();
            TokenType tokenType = currentToken.getTokenType();
            String tokenValue = currentToken.getValue();
            switch (tokenType) {


                case 开始对象:
                    checkExpectToken(tokenType, expectToken);
                    jsonArray.add(parseJsonObject()); // 数组对象就是这么存放的
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束数组);
                    break;

                case 开始数组:
                    checkExpectToken(tokenType, expectToken);
                    jsonArray.add(parseJsonArray());
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束数组);
                    break;
                case 结束数组:
                    checkExpectToken(tokenType, expectToken);
                    return jsonArray;
                case NULL:
                    checkExpectToken(tokenType, expectToken);
                    jsonArray.add(null);
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束数组);
                    break;
                case 布尔值:
                    checkExpectToken(tokenType, expectToken);
                    jsonArray.add(Boolean.valueOf(tokenValue));
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束数组);
                    break;
                case 字符串:
                    checkExpectToken(tokenType, expectToken);
                    jsonArray.add(tokenValue);
                    expectToken.clear();
                    expectToken.add(TokenType.逗号);
                    expectToken.add(TokenType.结束数组);
                    break;
                case 逗号:
                    checkExpectToken(tokenType, expectToken);
                    expectToken.clear();
                    expectToken.add(TokenType.字符串);
                    expectToken.add(TokenType.布尔值);
                    expectToken.add(TokenType.字符串);
                    expectToken.add(TokenType.开始对象);
                    expectToken.add(TokenType.结束对象);
                    expectToken.add(TokenType.开始数组);
                    expectToken.add(TokenType.结束数组);
                    expectToken.add(TokenType.NULL);
                    break;
                case END_DOCUMENT:
                    checkExpectToken(tokenType, expectToken);
                    return jsonArray;
            }
        }
        return null;
    }
}
